package com.lifeverse.entity;

import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 数字DNA实体类
 * 存储生命体的遗传信息和特征
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "digital_dna", indexes = {
    @Index(name = "idx_digital_dna_life_entity", columnList = "life_entity_id"),
    @Index(name = "idx_digital_dna_generation", columnList = "generation"),
    @Index(name = "idx_digital_dna_fitness", columnList = "fitness_score")
})
public class DigitalDNA extends BaseEntity {
    
    /**
     * 关联的生命体
     */
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "life_entity_id", nullable = false)
    private LifeEntity lifeEntity;
    
    /**
     * DNA序列（基因编码，JSON格式）
     */
    @Column(name = "gene_sequence", nullable = false, columnDefinition = "TEXT")
    private String geneSequence;
    
    /**
     * DNA版本号
     */
    @Column(name = "dna_version", nullable = false)
    private Integer dnaVersion = 1;
    
    /**
     * 世代数
     */
    @Column(name = "generation", nullable = false)
    private Integer generation = 1;
    
    /**
     * 适应度评分（0-1000）
     */
    @Column(name = "fitness_score", nullable = false, precision = 7, scale = 2)
    private BigDecimal fitnessScore = BigDecimal.valueOf(0.00);
    
    /**
     * 变异率（0-1）
     */
    @Column(name = "mutation_rate", nullable = false, precision = 5, scale = 4)
    private BigDecimal mutationRate = BigDecimal.valueOf(0.001);
    
    /**
     * 学习能力基因强度（0-100）
     */
    @Column(name = "learning_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal learningGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 创造力基因强度（0-100）
     */
    @Column(name = "creativity_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal creativityGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 协作基因强度（0-100）
     */
    @Column(name = "collaboration_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal collaborationGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 适应性基因强度（0-100）
     */
    @Column(name = "adaptability_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal adaptabilityGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 情感基因强度（0-100）
     */
    @Column(name = "emotion_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal emotionGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 逻辑基因强度（0-100）
     */
    @Column(name = "logic_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal logicGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 直觉基因强度（0-100）
     */
    @Column(name = "intuition_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal intuitionGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 社交基因强度（0-100）
     */
    @Column(name = "social_gene_strength", nullable = false, precision = 5, scale = 2)
    private BigDecimal socialGeneStrength = BigDecimal.valueOf(50.00);
    
    /**
     * 父DNA ID（用于追踪遗传来源）
     */
    @Column(name = "parent_dna_id")
    private Long parentDnaId;
    
    /**
     * 母DNA ID（用于追踪遗传来源）
     */
    @Column(name = "mother_dna_id")
    private Long motherDnaId;
    
    /**
     * 最后变异时间
     */
    @Column(name = "last_mutation_at")
    private LocalDateTime lastMutationAt;
    
    /**
     * 最后表达时间
     */
    @Column(name = "last_expression_at")
    private LocalDateTime lastExpressionAt;
    
    /**
     * DNA特征哈希值（用于快速比较）
     */
    @Column(name = "feature_hash", length = 64)
    private String featureHash;
    
    /**
     * DNA稳定性评分（0-100）
     */
    @Column(name = "stability_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal stabilityScore = BigDecimal.valueOf(100.00);
    
    /**
     * 表达活跃度（0-100）
     */
    @Column(name = "expression_activity", nullable = false, precision = 5, scale = 2)
    private BigDecimal expressionActivity = BigDecimal.valueOf(50.00);
    
    /**
     * DNA扩展属性（JSON格式存储）
     */
    @Column(name = "extended_attributes", columnDefinition = "TEXT")
    private String extendedAttributes;
    
    /**
     * 计算DNA的总体强度
     */
    public BigDecimal calculateOverallStrength() {
        return learningGeneStrength
                .add(creativityGeneStrength)
                .add(collaborationGeneStrength)
                .add(adaptabilityGeneStrength)
                .add(emotionGeneStrength)
                .add(logicGeneStrength)
                .add(intuitionGeneStrength)
                .add(socialGeneStrength)
                .divide(BigDecimal.valueOf(8), 2, java.math.RoundingMode.HALF_UP);
    }
    
    /**
     * 判断DNA是否稳定
     */
    public boolean isStable() {
        return stabilityScore.compareTo(BigDecimal.valueOf(70)) >= 0;
    }
    
    /**
     * 判断DNA是否活跃
     */
    public boolean isActive() {
        return expressionActivity.compareTo(BigDecimal.valueOf(30)) >= 0;
    }
    
    /**
     * 更新最后表达时间
     */
    public void updateLastExpressionTime() {
        this.lastExpressionAt = LocalDateTime.now();
    }
    
    /**
     * 更新最后变异时间
     */
    public void updateLastMutationTime() {
        this.lastMutationAt = LocalDateTime.now();
    }
    
    /**
     * 计算与另一个DNA的相似度（0-1）
     */
    public BigDecimal calculateSimilarity(DigitalDNA other) {
        if (other == null) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal totalDifference = BigDecimal.ZERO;
        totalDifference = totalDifference.add(learningGeneStrength.subtract(other.learningGeneStrength).abs());
        totalDifference = totalDifference.add(creativityGeneStrength.subtract(other.creativityGeneStrength).abs());
        totalDifference = totalDifference.add(collaborationGeneStrength.subtract(other.collaborationGeneStrength).abs());
        totalDifference = totalDifference.add(adaptabilityGeneStrength.subtract(other.adaptabilityGeneStrength).abs());
        totalDifference = totalDifference.add(emotionGeneStrength.subtract(other.emotionGeneStrength).abs());
        totalDifference = totalDifference.add(logicGeneStrength.subtract(other.logicGeneStrength).abs());
        totalDifference = totalDifference.add(intuitionGeneStrength.subtract(other.intuitionGeneStrength).abs());
        totalDifference = totalDifference.add(socialGeneStrength.subtract(other.socialGeneStrength).abs());
        
        BigDecimal maxPossibleDifference = BigDecimal.valueOf(800); // 8 genes * 100 max difference
        BigDecimal similarity = BigDecimal.ONE.subtract(totalDifference.divide(maxPossibleDifference, 4, java.math.RoundingMode.HALF_UP));
        
        return similarity.max(BigDecimal.ZERO);
    }
}